package cn.longwingstech.intelligence.agent.langchain4j;

import cn.longwingstech.intelligence.agent.langchain4j.tools.LangChainPDFGenerationTool;
import cn.longwingstech.intelligence.agent.utils.SpringContextUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import dev.langchain4j.data.image.Image;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.image.ImageModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.Duration;
@Slf4j
@Component
public class SuperAiServiceFactory {
    @Resource
    private ToolProvider mcpToolProvider;

    @Resource
    private LangChainPDFGenerationTool langChainPDFGenerationTool;
    /**
     * AI 服务实例缓存
     * 缓存策略：
     * - 最大缓存 1000 个实例
     * - 写入后 30 分钟过期
     * - 访问后 10 分钟过期
     */
    private final Cache<String, SuperAiService> serviceCache = Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(Duration.ofMinutes(30))
            .expireAfterAccess(Duration.ofMinutes(10))
            .removalListener((key, value, cause) -> {
                log.debug("AI 服务实例被移除，缓存键: {}, 原因: {}", key, cause);
            })
            .build();

    public SuperAiService createSuperAiService(String appid) {
        StreamingChatModel prototypeStreamingChatModel = SpringContextUtil.getBean("prototypeStreamingChatModel", StreamingChatModel.class);
        return serviceCache.get(appid,key-> AiServices.builder(SuperAiService.class)
                .streamingChatModel(prototypeStreamingChatModel)
                .chatMemoryProvider((memoryId) -> MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .maxMessages(10)
                        .build())
                .tools(langChainPDFGenerationTool)
                .toolProvider(mcpToolProvider)
                .hallucinatedToolNameStrategy(hallucinatedToolNameStrategy->{
                    return ToolExecutionResultMessage.from(hallucinatedToolNameStrategy, "hallucinated tool");
                })
                .build());
    }
}
